package com.huangwenshuo.futurestarschoolmanagement.security;

import com.alibaba.fastjson.JSONObject;
import com.huangwenshuo.futurestarschoolmanagement.config.RedisService;
import com.huangwenshuo.futurestarschoolmanagement.mapper.PermissionsMapper;
import com.huangwenshuo.futurestarschoolmanagement.mapper.UsersMapper;
import com.huangwenshuo.futurestarschoolmanagement.pojo.dto.JwtUserDto;
import com.huangwenshuo.futurestarschoolmanagement.pojo.dto.User;
import com.huangwenshuo.futurestarschoolmanagement.pojo.po.JwtUser;
import com.huangwenshuo.futurestarschoolmanagement.pojo.po.PermissionsPo;
import com.huangwenshuo.futurestarschoolmanagement.pojo.po.UsersPo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class CustomUserService implements UserDetailsService {

    private Logger log = LoggerFactory.getLogger(CustomUserService.class);

    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private PermissionsMapper permissionsMapper;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private RedisService redisService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        JwtUserDto jwtUserDto = RedisCheckUser(username);
        if(jwtUserDto != null){
            List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
            Map JwtMap = getPermissUrlandMethod(jwtUserDto);
            for(Object key : JwtMap.keySet()){
                Object value = JwtMap.get(key);
                GrantedAuthority grantedAuthority = new UrlGrantedAuthority((String) key,(String)value);
                grantedAuthorities.add(grantedAuthority);
            }
            User user = new User();
            user.setId(jwtUserDto.getId());
            user.setUsername(jwtUserDto.getUsername());
            user.setPassword(jwtUserDto.getPassword());
            user.setGrantedAuthorities(grantedAuthorities);
            UserDetails userDetails = new JwtUser(user);
            return userDetails ;

        }else {
            UsersPo usersPo = usersMapper.findByUsername(username);
            if (usersPo != null && usersPo.getUid() != null) {
                List<PermissionsPo> permissionsPos = permissionsMapper.findPermissionsByUid(usersPo.getUid());
                List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
                for (PermissionsPo permissionsPo : permissionsPos) {
                    if (permissionsPo != null && permissionsPo.getRoleCode()!=null) {

                        GrantedAuthority grantedAuthority = new MyGrantedAuthority(permissionsPo.getPermissionUrl(),permissionsPo.getPermissionMethod());
                        //1：此处将权限信息添加到 GrantedAuthority 对象中，在后面进行全权限验证时会使用GrantedAuthority 对象。
                        grantedAuthorities.add(grantedAuthority);
                    }
                }
                User user = new User();
                user.setId(usersPo.getUid());
                user.setUsername(usersPo.getUsername());
                user.setPassword(usersPo.getPassword());
                user.setGrantedAuthorities(grantedAuthorities);
                return new JwtUser(user);
            } else {
                throw new UsernameNotFoundException("用户名: " + username + " 不存在!");
            }
        }
    }

    public  JwtUserDto RedisCheckUser(String username) {

        //从redis里边取出用户信息
        String stringValue = redisService.get("fssm"+":"+username);

        if (stringValue != null) {
            try {
                // 验证当前请求的session是否是已登录的session
                //json转成JwtUser对象
                JwtUserDto jwtUserDto = JSONObject.parseObject(stringValue,JwtUserDto.class);
                return jwtUserDto;
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return null;
    }

    //因为jwtUserDto里边存的是一个List集合，然后List集合里边是Map，所以要在这里把数据拆开再组装，只返回一个带有权限的Map
    public Map getPermissUrlandMethod(JwtUserDto jwtUserDto){
        Map jwtMapDto = new HashMap();
        List jwtList = (List) Collections.singletonList(jwtUserDto.getAuthorities()).get(0);
        for(int i =0;i<jwtList.size();i++){
            Map jwtMap = (Map) jwtList.get(i);
            String PermissionUrlS = (String) jwtMap.get("permissionUrl");
            String methodS = (String) jwtMap.get("method");
            jwtMapDto.put(PermissionUrlS,methodS);
        }
        return jwtMapDto;
    }

}
